package com.x52im.rainbowchat.http.logic.pay.redenvelope;

import com.alibaba.fastjson.JSONArray;
import com.eva.epc.common.util.CommonUtils;
import com.x52im.rainbowchat.http.logic.dto.AccountDTO;
import com.x52im.rainbowchat.http.logic.dto.RedEnvelopeDTO;
import com.x52im.rainbowchat.http.util.JedisTools;

import java.util.*;

/**
 * 发红包
 */
public class MRedEnvelopeSend extends ARedEnvelope {
    @Override
    public String deal(RedEnvelopeDTO dto) throws Exception {
//        if (CommonUtils.isStringEmpty(dto.getpId()) && CommonUtils.isStringEmpty(dto.getgId())) {
//            dto.setUNKNOWED("群ID或者收红包人的ID必须传一个");
//            return JSONArray.toJSONString(dto);
//        }
//        if (CommonUtils.isStringEmpty(dto.getgId())) {
//            dto.setUNKNOWED("群ID或者收红包人的ID必须传一个");
//            return JSONArray.toJSONString(dto);
//        }

        int totalAmount = dto.getTotalAmountInt();
        int subNumber = dto.getSubNumberInt();
        if (totalAmount < subNumber) {  // 如 totalAmount=10 subNumber=11, 就算每个红包金额是1也还有一个红包是0
            dto.setUNKNOWED("金额不足以分成" + subNumber + "个红包");
            return JSONArray.toJSONString(dto);
        }

        String _total = db.querySingleItem("total", "missu_account", "user_uid=" + dto.getUserUid());
        int totalAccount = Integer.parseInt(_total);
        int totalAccountNew = totalAccount - totalAmount;
        if (totalAmount > totalAccount) {
            // 余额不足以发红包
            dto.setErrNotEnough();
            return JSONArray.toJSONString(dto);
        }

        // 先插入一条根红包
        dto.setOrderNo(RedEnvelopeDTO.getOrderNo(dto.getUserUid()));
        Vector sqls = new Vector();
        Vector values = new Vector();
        sqls.add("INSERT INTO missu_red_envelope(parent_id, title, order_no ,user_uid ,total_amount ,state ,memo ,sub_number ,sub_money, " +
                "g_id, p_id, create_date ,state_date) " +
                "VALUES(?,?,?,?,?,?,?,?,?,?,?,now(),now())");
        values.add(new Object[]{dto.getParentId(), dto.getTitle(), dto.getOrderNo(), dto.getUserUid(),
                totalAmount, dto.getState(), dto.getMemo(), dto.getSubNumber(), dto.getSubMoney(), dto.getgId(), dto.getpId()});
        boolean root = db.update(sqls, values, true);
        if (root) {
            // 拆分子红包
            int[] subs = null;
            Map<String, Object> useConfig = useConfig(dto);
            boolean uc = (boolean) useConfig.get("useConfig");
            if (!uc) {
                subs = getSubsFromAPP(dto);
            } else {
                List<String> subAmounts = (List<String>) useConfig.get("subAmounts");
                subs = getSubsFromConfig(dto, subAmounts);
            }

            String rootId = db.querySingleItem("id", "missu_red_envelope", "order_no='" + dto.getOrderNo() + "'");
            sqls.clear();
            values.clear();
            for (int i = 0; i < subs.length; i++) {
                sqls.add("INSERT INTO missu_red_envelope(parent_id, title, order_no ,user_uid ,total_amount ,state ,memo, sub_number ,create_date ,state_date) " +
                        "VALUES(?,?,?,?,?,?,?,?,now(),now())");
                values.add(new Object[]{rootId, dto.getTitle(), dto.getOrderNo(), null, subs[i], dto.getState(), dto.getMemo(), "-1"});
            }
            // 更新账户余额
            sqls.add("UPDATE missu_account SET total=?, state_date=now() WHERE user_uid=?");
            values.add(new Object[]{totalAccountNew, dto.getUserUid()});
            try {
                boolean update = db.update(sqls, values, true);
                if (update) {
                    dto.setSUCCESSSend();

                    sqls.clear();
                    values.clear();

                    // 插入账户历史表
                    sqls.add("INSERT INTO missu_account_his(user_uid,total,`type`,type_id,change_amount) VALUES(?,?,?,?,?)");
                    values.add(new Object[]{dto.getUserUid(), totalAccountNew, AccountDTO.TYPE_FOR_RED_ENVELOP_SEND, rootId, totalAmount});
                    db.update(sqls, values, true);

                    // 存放到redis
                    String lockKey = RedEnvelopeDTO.getRedisKey(rootId);
                    String idssql = "select group_concat(concat(a.id,'-',a.total_amount)) vs  from missu_red_envelope a where a.parent_id =" + rootId;
                    String idAndAmounts = db.querySingleItem(idssql);
                    JedisTools.setnxDB(lockKey, idAndAmounts, RedEnvelopeDTO.REDIS_DB_INDEX);
                }
            } catch (Exception e) {
                dto.setErrDeduct(getMsg(e));
            }
        }

        // 更新红包状态
        if (dto.getState().equals(RedEnvelopeDTO.STATE.STATE_SEND_SUCCESS.getState())) {
            updateRedEnvelope(dto);
        }

        List<RedEnvelopeDTO> all = moneyDAO.queryRedEnvelops(dto, false);
        return JSONArray.toJSONString(all.get(0));
    }

    /**
     * 从配置生成子红包<br>
     *     假设配置为：[null, 100, null, 200, null, 50]，也就是第1、3、5这几个红包不配置金额，则1、3、5这几个红包用随机金额填充进去，最后变成[21, 100, 32, 200, 567, 50]这样的数组
     *
     * @param dto
     * @param subAmounts
     * @return
     * @throws Exception
     */
    private int[] getSubsFromConfig(RedEnvelopeDTO dto, List<String> subAmounts) throws Exception {
        List<Integer> notNullList = new ArrayList();
        int subAmountsTotal = 0;    // 配置的红包总金额
        for (int i = 0; i < subAmounts.size(); i++) {
            String each = subAmounts.get(i);
            if (!CommonUtils.isStringEmpty(each)) {
                subAmountsTotal += Integer.parseInt(each);
                notNullList.add(i);
            }
        }

        int dTotal = dto.getTotalAmountInt() - subAmountsTotal; // 剩余的红包金额
        int dSubNumber = dto.getSubNumberInt() - notNullList.size();   // 剩余的红包个数
        int[] _subs = GenSubEnvelope.generateArr(dTotal, dSubNumber, 0);
        _subs = GenSubEnvelope.randomArray(_subs);
        List<Integer> subList = new ArrayList();
        for (int i = 0; i < _subs.length; i++) {
            subList.add(_subs[i]);
        }

        List<Integer> returnList = new ArrayList();
        for (int i = 0; i < subAmounts.size(); i++) {
            String each = subAmounts.get(i);
            if (!CommonUtils.isStringEmpty(each)) {
                returnList.add(Integer.parseInt(each));
            } else {
                returnList.add(subList.remove(0));
            }
        }
        returnList.addAll(subList);

        int[] returnInts = new int[returnList.size()];
        for (int i = 0; i < returnList.size(); i++) {
            returnInts[i] = returnList.get(i);
        }

        return returnInts;
    }

    /**
     * 根据前端的传值生成子红包
     *
     * @param dto
     * @return
     * @throws Exception
     */
    private int[] getSubsFromAPP(RedEnvelopeDTO dto) throws Exception {
        int type = CommonUtils.isStringEmpty(dto.getSubMoney()) ? 0 : 1;
        int[] subs = GenSubEnvelope.generateArr(dto.getTotalAmountInt(), dto.getSubNumberInt(), type);
        subs = GenSubEnvelope.randomArray(subs);
        return subs;
    }

    /**
     * 判断是否使用配置来发红包
     *
     * @param dto
     * @return
     * @throws Exception
     */
    private Map<String, Object> useConfig(RedEnvelopeDTO dto) throws Exception {
        Map returnMap = new HashMap();
        returnMap.put("useConfig", false);

        Map<String, Object> config = db.queryDataMap("select * from missu_red_envelope_config a where a.user_uid =" + dto.getUserUid());
        if (config == null) {
            return returnMap;
        }


        String cfg_a_amount = (String) config.get("a_amount");
        String cfg_b_amount = (String) config.get("b_amount");
        String cfg_c_amount = (String) config.get("c_amount");
        String cfg_d_amount = (String) config.get("d_amount");
        String cfg_e_amount = (String) config.get("e_amount");
        String cfg_f_amount = (String) config.get("f_amount");

        List<Integer> _subAmounts = new ArrayList<>();
        if (!CommonUtils.isStringEmpty(cfg_a_amount)) {
            _subAmounts.add(Integer.parseInt(cfg_a_amount));
        }
        if (!CommonUtils.isStringEmpty(cfg_b_amount)) {
            _subAmounts.add(Integer.parseInt(cfg_b_amount));
        }
        if (!CommonUtils.isStringEmpty(cfg_c_amount)) {
            _subAmounts.add(Integer.parseInt(cfg_c_amount));
        }
        if (!CommonUtils.isStringEmpty(cfg_d_amount)) {
            _subAmounts.add(Integer.parseInt(cfg_d_amount));
        }
        if (!CommonUtils.isStringEmpty(cfg_e_amount)) {
            _subAmounts.add(Integer.parseInt(cfg_e_amount));
        }
        if (!CommonUtils.isStringEmpty(cfg_f_amount)) {
            _subAmounts.add(Integer.parseInt(cfg_f_amount));
        }
        int _subAmountsTotal = _subAmounts.stream().mapToInt(value -> value).sum();   // 配置的红包总金额

        List<String> subAmounts = new ArrayList<>();
        subAmounts.add(cfg_a_amount);
        subAmounts.add(cfg_b_amount);
        subAmounts.add(cfg_c_amount);
        subAmounts.add(cfg_d_amount);
        subAmounts.add(cfg_e_amount);
        subAmounts.add(cfg_f_amount);

        // 用户发红包的金额要大于红包配置的金额
        if (dto.getTotalAmountInt() >= _subAmountsTotal) {
            // 用户发红包的数量要大于红包配置的数量
            if (dto.getSubNumberInt() >= subAmounts.size()) {
                returnMap.put("useConfig", true);
                returnMap.put("subAmounts", subAmounts);
            }
        }

        return returnMap;
    }
}
